﻿using Microsoft.Extensions.DependencyInjection;
using MongoDB;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Furion.DatabaseAccessor
{
    /// <summary>
    ///  非泛型 MongoDB 仓储
    /// </summary>
    public partial class MongoDbRepository : IMongoDbRepository
    {
        /// <summary>
        /// 服务提供器
        /// </summary>
        private readonly IServiceProvider _serviceProvider;
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="serviceProvider">服务提供器</param>
        public MongoDbRepository(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
        }

        /// <summary>
        /// 切换仓储
        /// </summary>
        /// <typeparam name="TDocument">实体类型</typeparam>
        /// <returns>仓储</returns>
        public virtual IMongoDbRepository<TDocument> Change<TDocument>()
            where TDocument : class, IEntity<string>, new()
        {
            return _serviceProvider.GetService<IMongoDbRepository<TDocument>>();
        }

        /// <summary>
        /// 解析服务
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <returns></returns>
        public TService GetService<TService>()
        {
            return _serviceProvider.GetRequiredService<TService>();
        }

        /// <summary>
        /// 切换仓储
        /// </summary>
        /// <typeparam name="TDocument">实体类型</typeparam>
        /// <typeparam name="TKey">主键类型</typeparam>
        /// <returns>仓储</returns>
        IMongoDbRepository<TDocument, TKey> IMongoDbRepository.Change<TDocument, TKey>()
        {
            return _serviceProvider.GetService<IMongoDbRepository<TDocument, TKey>>();
        }
    }

    /// <summary>
    /// MongoDB 仓储实现类型
    /// </summary>
    /// <typeparam name="TDocument">实体类型</typeparam>
    public partial class MongoDbRepository<TDocument> : MongoDbRepository<TDocument, string>, IMongoDbRepository<TDocument>
        where TDocument : class, IEntity<string>, new()
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mongoDbRepository">非泛型 MongoDB 仓储</param>
        /// <param name="db">初始化 MongoDB 客户端</param>
        public MongoDbRepository(IMongoDbRepository mongoDbRepository, IMongoDatabase db)
            : base(mongoDbRepository, db)
        {
        }
    }
    /// <summary>
    /// MongoDB 仓储实现类
    /// </summary>
    /// <typeparam name="TDocument">实体类型</typeparam>
    /// <typeparam name="TKey">主键类型</typeparam>
    public partial class MongoDbRepository<TDocument, TKey> : IMongoDbRepository<TDocument, TKey>
        where TDocument : IEntity<TKey>, new()
        where TKey : class
    {
        /// <summary>
        /// 非泛型 MongoDB 仓储
        /// </summary>
        private readonly IMongoDbRepository _mongoDbRepository;

        /// <summary>
        /// 初始化 MongoDB 客户端
        /// </summary>
        private readonly IMongoDatabase _db;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="mongoDbRepository">非泛型仓储</param>
        /// <param name="db">初始化 MongoDB 客户端</param>
        public MongoDbRepository(IMongoDbRepository mongoDbRepository, IMongoDatabase db)
        {
            _mongoDbRepository = mongoDbRepository;
            DynamicDbContext = DbContext = _db = db;
            Entities = db.GetCollection<TDocument>(typeof(TDocument).Name);
        }

        /// <summary>
        /// 实体集合
        /// </summary>
        public virtual IMongoCollection<TDocument> Entities { get; }

        /// <summary>
        /// 数据库上下文
        /// </summary>
        public virtual IMongoDatabase DbContext { get; }

        /// <summary>
        /// 动态数据库上下文
        /// </summary>
        public virtual dynamic DynamicDbContext { get; }

        /// <summary>
        /// 根据表达式查询多条记录
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual IQueryable<TDocument> Where(Expression<Func<TDocument, bool>> predicate)
        {
            return AsQueryable(predicate);
        }

        /// <summary>
        /// 构建查询分析器
        /// </summary>
        /// <returns></returns>
        public virtual IQueryable<TDocument> AsQueryable()
        {
            return Entities.AsQueryable();
        }

        /// <summary>
        /// 构建查询分析器
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual IQueryable<TDocument> AsQueryable(Expression<Func<TDocument, bool>> predicate)
        {
            return Entities.AsQueryable().Where(predicate);
        }

        /// <summary>
        /// 直接返回数据库结果
        /// </summary>
        /// <returns></returns>
        public virtual List<TDocument> AsEnumerable()
        {
            return AsQueryable().ToList();
        }

        /// <summary>
        /// 直接返回数据库结果
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public virtual List<TDocument> AsEnumerable(Expression<Func<TDocument, bool>> predicate)
        {
            return AsQueryable(predicate).ToList();
        }

        /// <summary>
        /// 直接返回数据库结果
        /// </summary>
        /// <returns></returns>
        public async virtual Task<List<TDocument>> AsAsyncEnumerable()
        {
            return await Task.FromResult(AsQueryable().ToList());
        }
        /// <summary>
        /// 直接返回数据库结果
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        public async virtual Task<List<TDocument>> AsAsyncEnumerable(Expression<Func<TDocument, bool>> predicate)
        {
            return await Task.FromResult(AsQueryable(predicate).ToList());
        }


        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns></returns>
        public virtual bool Exists(Expression<Func<TDocument, bool>> predicate)
        {
            return this.Entities.AsQueryable().Any(predicate);
        }

        /// <summary>
        /// 判断是否存在
        /// </summary>
        /// <param name="predicate">条件</param>
        /// <returns></returns>
        public async virtual Task<bool> ExistsAsync(Expression<Func<TDocument, bool>> predicate)
        {
            return await Task.FromResult(this.Entities.AsQueryable().Any(predicate));
        }

        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <returns></returns>
        public virtual long Count()
        {
            return Count(new BsonDocument());
        }

        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <returns></returns>
        public virtual long Count(Expression<Func<TDocument, bool>> expression)
        {
            return Entities.CountDocuments(expression);
        }
        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public virtual long Count(FilterDefinition<TDocument> filter)
        {
            return Entities.CountDocuments(filter);
        }

        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <returns></returns>
        public async virtual Task<long> CountAsync()
        {
            return await CountAsync(new BsonDocument());
        }
        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <returns></returns>
        public async virtual Task<long> CountAsync(Expression<Func<TDocument, bool>> expression)
        {
            return await Entities.CountDocumentsAsync(expression);
        }
        /// <summary>
        /// 获取记录数
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public async virtual Task<long> CountAsync(FilterDefinition<TDocument> filter)
        {
            return await Entities.CountDocumentsAsync(filter);
        }

        #region 分页
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public virtual List<TDocument> PageList(int pageIndex, int pageSize)
        {
            return Entities.Find(new BsonDocument()).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual List<TNewProjection> PageList<TNewProjection>(int pageIndex, int pageSize,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(new BsonDocument()).Project(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="filter">过滤器</param>
        /// <param name="sort">排序条件</param>
        /// <returns></returns>
        public virtual List<TDocument> PageList(int pageIndex, int pageSize, FilterDefinition<TDocument> filter, SortDefinition<TDocument> sort)
        {
            return Entities.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="filter">过滤器</param>
        /// <param name="sort">排序条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual List<TNewProjection> PageList<TNewProjection>(int pageIndex, int pageSize, FilterDefinition<TDocument> filter, SortDefinition<TDocument> sort, Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(filter).Project(projection).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="where">筛选条件</param>
        /// <param name="sort">排序条件</param>
        /// <returns></returns>
        public virtual List<TDocument> PageList(int pageIndex, int pageSize, Expression<Func<TDocument, bool>> where, SortDefinition<TDocument> sort)
        {
            return Entities.Find(where).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
        }
        /// <summary>
        /// 获取分页数据
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="where">筛选条件</param>
        /// <param name="sort">排序条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual List<TNewProjection> PageList<TNewProjection>(int pageIndex, int pageSize,
            Expression<Func<TDocument, bool>> where, SortDefinition<TDocument> sort, Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(where).Project(projection).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToList();
        }

        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <returns></returns>
        public async virtual Task<List<TDocument>> PageListAsync(int pageIndex, int pageSize)
        {
            return await Entities.Find(new BsonDocument()).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }
        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async Task<List<TNewProjection>> PageListAsync<TNewProjection>(int pageIndex, int pageSize,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(new BsonDocument()).Project(projection).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }
        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="filter">过滤器</param>
        /// <param name="sort">排序条件</param>
        /// <returns></returns>
        public async Task<List<TDocument>> PageListAsync(int pageIndex, int pageSize, FilterDefinition<TDocument> filter,
            SortDefinition<TDocument> sort)
        {
            return await Entities.Find(filter).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }
        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="filter">过滤器</param>
        /// <param name="sort">排序条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async Task<List<TNewProjection>> PageListAsync<TNewProjection>(int pageIndex, int pageSize,
            FilterDefinition<TDocument> filter, SortDefinition<TDocument> sort, Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(filter).Project(projection).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }

        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="where">筛选条件</param>
        /// <param name="sort">排序条件</param>
        /// <returns></returns>
        public async Task<List<TDocument>> PageListAsync(int pageIndex, int pageSize, Expression<Func<TDocument, bool>> where,
            SortDefinition<TDocument> sort)
        {
            return await Entities.Find(where).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }

        /// <summary>
        /// 异步获取分页数据
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="pageIndex">页次</param>
        /// <param name="pageSize">页大小</param>
        /// <param name="where">筛选条件</param>
        /// <param name="sort">排序条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async Task<List<TNewProjection>> PageListAsync<TNewProjection>(int pageIndex, int pageSize,
            Expression<Func<TDocument, bool>> where, SortDefinition<TDocument> sort, Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(where).Project(projection).Sort(sort).Skip((pageIndex - 1) * pageSize).Limit(pageSize).ToListAsync();
        }
        #endregion

        #region 查询
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <param name="id">objectId</param>
        /// <returns></returns>
        public virtual TDocument Get(TKey id)
        {
            return Get(Builders<TDocument>.Filter.Eq(d => d.Id, id));
        }
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <returns></returns>
        public virtual TDocument Get(Expression<Func<TDocument, bool>> expression)
        {
            return Entities.Find(expression).FirstOrDefault();
        }
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="expression">筛选条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual TNewProjection Get<TNewProjection>(Expression<Func<TDocument, bool>> expression,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(expression).Project(projection).FirstOrDefault();
        }
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public virtual TDocument Get(FilterDefinition<TDocument> filter)
        {
            return Entities.Find(filter).FirstOrDefault();
        }
        /// <summary>
        /// 获取单个对象
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="filter">过滤器</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual TNewProjection Get<TNewProjection>(FilterDefinition<TDocument> filter,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(filter).Project(projection).FirstOrDefault();
        }


        /// <summary>
        /// 异步获取单个对象
        /// </summary>
        /// <param name="id">objectId</param>
        /// <returns></returns>
        public async Task<TDocument> GetAsync(TKey id)
        {
            return await GetAsync(Builders<TDocument>.Filter.Eq(d => d.Id, id));
        }

        /// <summary>
        /// 异步获取单个对象
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <returns></returns>
        public async virtual Task<TDocument> GetAsync(Expression<Func<TDocument, bool>> expression)
        {
            return await Entities.Find(expression).FirstOrDefaultAsync();
        }
        /// <summary>
        /// 异步获取单个对象
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="expression">筛选条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async virtual Task<TNewProjection> GetAsync<TNewProjection>(Expression<Func<TDocument, bool>> expression,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(expression).Project(projection).FirstOrDefaultAsync();
        }
        /// <summary>
        /// 异步获取单个对象
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public async virtual Task<TDocument> GetAsync(FilterDefinition<TDocument> filter)
        {
            return await Entities.Find(filter).FirstOrDefaultAsync();
        }
        /// <summary>
        /// 异步获取单个对象
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="filter">过滤器</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async virtual Task<TNewProjection> GetAsync<TNewProjection>(FilterDefinition<TDocument> filter,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(filter).Project(projection).FirstOrDefaultAsync();
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="expression">筛选条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual List<TNewProjection> Find<TNewProjection>(Expression<Func<TDocument, bool>> expression,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(expression).Project(projection).ToList();
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public virtual List<TDocument> Find(FilterDefinition<TDocument> filter)
        {
            return Entities.Find(filter).ToList();
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="filter">过滤器</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public virtual List<TNewProjection> Find<TNewProjection>(FilterDefinition<TDocument> filter,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return Entities.Find(filter).Project(projection).ToList();
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="expression">筛选条件</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async virtual Task<List<TNewProjection>> FindAsync<TNewProjection>(Expression<Func<TDocument, bool>> expression,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(expression).Project(projection).ToListAsync();
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public async virtual Task<List<TDocument>> FindAsync(FilterDefinition<TDocument> filter)
        {
            return await Entities.Find(filter).ToListAsync();
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <typeparam name="TNewProjection">新实体类型</typeparam>
        /// <param name="filter">过滤器</param>
        /// <param name="projection">新实体映射</param>
        /// <returns></returns>
        public async virtual Task<List<TNewProjection>> FindAsync<TNewProjection>(FilterDefinition<TDocument> filter,
            Expression<Func<TDocument, TNewProjection>> projection)
        {
            return await Entities.Find(filter).Project(projection).ToListAsync();
        }
        #endregion

        #region 插入
        /// <summary>
        /// 插入
        /// </summary>
        /// <param name="value">对象</param>
        public void Insert(TDocument value)
        {
            Entities.InsertOne(value);
        }

        /// <summary>
        /// 异步插入
        /// </summary>
        /// <param name="value">对象</param>
        /// <returns></returns>
        public async Task InsertAsync(TDocument value)
        {
            await Entities.InsertOneAsync(value);
        }

        /// <summary>
        /// 批量插入
        /// </summary>
        /// <param name="values">对象集合</param>
        public void BatchInsert(IEnumerable<TDocument> values)
        {
            Entities.InsertMany(values);
        }

        /// <summary>
        /// 异步批量插入
        /// </summary>
        /// <param name="values">对象集合</param>
        /// <returns></returns>
        public async Task BatchInsertAsync(IEnumerable<TDocument> values)
        {
            await Entities.InsertManyAsync(values);
        }
        #endregion

        #region 更新
        /// <summary>
        /// 覆盖更新
        /// </summary>
        /// <param name="value">对象</param>
        /// <returns></returns>
        public virtual ReplaceOneResult Update(TDocument value)
        {
            return Entities.ReplaceOne(Builders<TDocument>.Filter.Eq(d => d.Id, value.Id), value);
        }

        /// <summary>
        /// 局部更新
        /// </summary>
        /// <param name="id">记录ID</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public virtual UpdateResult Update(TKey id, UpdateDefinition<TDocument> update)
        {
            return Update(Builders<TDocument>.Filter.Eq(d => d.Id, id), update);
        }
        /// <summary>
        /// 局部更新
        /// </summary>
        /// <param name="id">记录ID</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public async virtual Task<UpdateResult> UpdateAsync(TKey id, UpdateDefinition<TDocument> update)
        {
            return await UpdateAsync(Builders<TDocument>.Filter.Eq(d => d.Id, id), update);
        }

        /// <summary>
        /// 局部更新
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public virtual UpdateResult Update(Expression<Func<TDocument, bool>> expression, UpdateDefinition<TDocument> update)
        {
            return Entities.UpdateMany(expression, update);
        }
        /// <summary>
        /// 局部更新
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public virtual UpdateResult UpdateMany(Expression<Func<TDocument, bool>> expression, UpdateDefinition<TDocument> update)
        {
            return Entities.UpdateMany(expression, update);
        }
        /// <summary>
        /// 局部更新
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public virtual UpdateResult Update(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update)
        {
            return Entities.UpdateOne(filter, update);
        }

        /// <summary>
        /// 异步局部更新（仅更新一条记录）
        ///     <para><![CDATA[expression 参数示例：x => x.Id == 1 && x.Age > 18 && x.Gender == 0]]></para>
        ///     <para><![CDATA[entity 参数示例：y => new T{ RealName = "Ray", Gender = 1}]]></para>
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <param name="entity">更新条件</param>
        /// <returns></returns>
        public virtual UpdateResult Update(Expression<Func<TDocument, bool>> expression, Expression<Action<TDocument>> entity)
        {
            var fieldList = new List<UpdateDefinition<TDocument>>();

            var param = entity.Body as MemberInitExpression;
            if (param != null)
            {
                foreach (var item in param.Bindings)
                {
                    var propertyName = item.Member.Name;
                    object propertyValue = null;
                    var memberAssignment = item as MemberAssignment;
                    if (memberAssignment == null) continue;
                    if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
                    {
                        var constantExpression = memberAssignment.Expression as ConstantExpression;
                        if (constantExpression != null)
                            propertyValue = constantExpression.Value;
                    }
                    else
                    {
                        propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
                    }

                    if (propertyName != "_id") //实体键_id不允许更新
                    {
                        fieldList.Add(Builders<TDocument>.Update.Set(propertyName, propertyValue));
                    }
                }
            }
            return Entities.UpdateOne(expression, Builders<TDocument>.Update.Combine(fieldList));
        }

        /// <summary>
        ///     异步局部更新（仅更新一条记录）
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public async virtual Task<UpdateResult> UpdateAsync(FilterDefinition<TDocument> filter, UpdateDefinition<TDocument> update)
        {
            return await Entities.UpdateOneAsync(filter, update);
        }

        /// <summary>
        ///     异步局部更新（仅更新一条记录）
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public async virtual Task<UpdateResult> UpdateAsync<T>(Expression<Func<TDocument, bool>> expression,
            UpdateDefinition<TDocument> update)
        {
            return await Entities.UpdateOneAsync(expression, update);
        }
        /// <summary>
        /// 异步局部更新（仅更新多条记录）
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <param name="update">更新条件</param>
        /// <returns></returns>
        public async virtual Task<UpdateResult> UpdateManyAsync(Expression<Func<TDocument, bool>> expression,
            UpdateDefinition<TDocument> update)
        {
            return await Entities.UpdateManyAsync(expression, update);
        }

        /// <summary>
        /// 异步局部更新（仅更新一条记录）
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <param name="entity">更新条件</param>
        /// <returns></returns>
        public async virtual Task<UpdateResult> UpdateAsync(Expression<Func<TDocument, bool>> expression,
            Expression<Action<TDocument>> entity)
        {
            var fieldList = new List<UpdateDefinition<TDocument>>();

            var param = entity.Body as MemberInitExpression;
            if (param != null)
            {
                foreach (var item in param.Bindings)
                {
                    var propertyName = item.Member.Name;
                    object propertyValue = null;
                    var memberAssignment = item as MemberAssignment;
                    if (memberAssignment == null) continue;
                    if (memberAssignment.Expression.NodeType == ExpressionType.Constant)
                    {
                        var constantExpression = memberAssignment.Expression as ConstantExpression;
                        if (constantExpression != null)
                            propertyValue = constantExpression.Value;
                    }
                    else
                    {
                        propertyValue = Expression.Lambda(memberAssignment.Expression, null).Compile().DynamicInvoke();
                    }

                    if (propertyName != "_id") //实体键_id不允许更新
                    {
                        fieldList.Add(Builders<TDocument>.Update.Set(propertyName, propertyValue));
                    }
                }
            }
            return await Entities.UpdateOneAsync(expression, Builders<TDocument>.Update.Combine(fieldList));
        }

        /// <summary>
        ///     异步覆盖更新
        /// </summary>
        /// <param name="value">对象</param>
        /// <returns></returns>
        public async virtual Task<ReplaceOneResult> UpdateAsync(TDocument value)
        {
            return await Entities.ReplaceOneAsync(Builders<TDocument>.Filter.Eq(d => d.Id, value.Id), value);
        }
        #endregion

        #region 删除
        /// <summary>
        /// 删除指定对象
        /// </summary>
        /// <param name="id">对象Id</param>
        /// <returns></returns>
        public virtual DeleteResult Delete(TKey id)
        {
            return Entities.DeleteOne(Builders<TDocument>.Filter.Eq(d => d.Id, id));
        }

        /// <summary>
        /// 删除指定对象
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <returns></returns>
        public virtual DeleteResult Delete(Expression<Func<TDocument, bool>> expression)
        {
            return Entities.DeleteOne(expression);
        }

        /// <summary>
        /// 异步删除指定对象
        /// </summary>
        /// <param name="id">对象Id</param>
        /// <returns></returns>
        public async virtual Task<DeleteResult> DeleteAsync(TKey id)
        {
            return await Entities.DeleteOneAsync(Builders<TDocument>.Filter.Eq(d => d.Id, id));
        }

        /// <summary>
        /// 异步删除指定对象
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <returns></returns>
        public async virtual Task<DeleteResult> DeleteAsync(Expression<Func<TDocument, bool>> expression)
        {
            return await Entities.DeleteOneAsync(expression);
        }

        /// <summary>
        /// 批量删除对象
        /// </summary>
        /// <param name="ids">ID集合</param>
        /// <returns></returns>
        public virtual DeleteResult BatchDelete(IEnumerable<ObjectId> ids)
        {
            var filter = Builders<TDocument>.Filter.In("_id", ids);
            return Entities.DeleteMany(filter);
        }

        /// <summary>
        /// 批量删除对象
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public virtual DeleteResult BatchDelete(FilterDefinition<TDocument> filter)
        {
            return Entities.DeleteMany(filter);
        }

        /// <summary>
        /// 批量删除对象
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <returns></returns>
        public virtual DeleteResult BatchDelete(Expression<Func<TDocument, bool>> expression)
        {
            return Entities.DeleteMany(expression);
        }

        /// <summary>
        /// 异步批量删除对象
        /// </summary>
        /// <param name="ids">ID集合</param>
        /// <returns></returns>
        public async virtual Task<DeleteResult> BatchDeleteAsync(IEnumerable<ObjectId> ids)
        {
            var filter = Builders<TDocument>.Filter.In("_id", ids);
            return await Entities.DeleteManyAsync(filter);
        }

        /// <summary>
        /// 异步批量删除对象
        /// </summary>
        /// <param name="filter">过滤器</param>
        /// <returns></returns>
        public async virtual Task<DeleteResult> BatchDeleteAsync(FilterDefinition<TDocument> filter)
        {
            return await Entities.DeleteManyAsync(filter);
        }

        /// <summary>
        /// 异步批量删除对象
        /// </summary>
        /// <param name="expression">筛选条件</param>
        /// <returns></returns>
        public async virtual Task<DeleteResult> BatchDeleteAsync(Expression<Func<TDocument, bool>> expression)
        {
            return await Entities.DeleteManyAsync(expression);
        }
        #endregion


        /// <summary>
        /// 切换仓储
        /// </summary>
        /// <typeparam name="TChangeEntity">实体类型</typeparam>
        /// <returns>仓储</returns>
        public virtual IMongoDbRepository<TChangeEntity> Change<TChangeEntity>()
            where TChangeEntity : class, IEntity<string>, new()
        {
            return _mongoDbRepository.Change<TChangeEntity>();
        }

        /// <summary>
        /// 切换仓储
        /// </summary>
        /// <typeparam name="TChangeEntity">实体类型</typeparam>
        /// <typeparam name="TChangeKey">主键类型</typeparam>
        /// <returns>仓储</returns>
        public virtual IMongoDbRepository<TChangeEntity, TChangeKey> Change<TChangeEntity, TChangeKey>()
            where TChangeEntity : class, IEntity<TChangeKey>, new()
            where TChangeKey : class
        {
            return _mongoDbRepository.GetService<IMongoDbRepository<TChangeEntity, TChangeKey>>();
        }
    }

}
